package com.zhen.controller;

import java.io.File;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.map.CaseInsensitiveMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.zhen.annotation.FileBean;
import com.zhen.annotation.HtmlBean;
import com.zhen.annotation.SpringAnnotationScanner;
import com.zhen.pojo.Columns;
import com.zhen.process.BaseProcess;
import com.zhen.service.ColumnsService;
import com.zhen.service.DataBatchInsertCustomService;
import com.zhen.service.SchemataService;
import com.zhen.service.TablesService;
import com.zhen.util.FileUtils;
import com.zhen.util.JsonUtils;
import com.zhen.util.UrlUtil;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

/**
 * Created by Administrator on 2018/6/24.
 */
@Controller
@RequestMapping("/freemarker")
@JsonIgnoreProperties
public class FreemarkerController {
	
	@Autowired
	private SchemataService schemataService;
	@Autowired
	private TablesService tablesService;
	@Autowired
	private ColumnsService columnsService;
	@Autowired
	private SpringAnnotationScanner springAnnotationScanner;
	@Autowired
	private DataBatchInsertCustomService dataBatchInsertCustomService;
	
	@RequestMapping("/index")
	public ModelAndView say(String filePath) {
		ModelAndView mav = new ModelAndView();
		mav.setViewName("html/index");
		return mav;
	}
	
	@GetMapping("/schematas")
	@ResponseBody
	public Object schematas(){
		return schemataService.findSchematas();
	}
	
	@GetMapping("/tables")
	@ResponseBody
	public Object tables(String dbName){
		return tablesService.findByTableSchema(dbName);
	}
	
	@GetMapping("/column")
	@ResponseBody
	public Object column(String tableSchema, String tableName){
		return columnsService.findColumnsBySchemaAndTableName(tableSchema, tableName);
	}
	@GetMapping("/process")
	@ResponseBody
	public Object process(){
		return springAnnotationScanner.getClassList();
	}
	@PostMapping("/execute")
	@ResponseBody
	public Object execute(String columnsStr,String tableName,String dbName, int number){
		
		try {
			columnsStr = columnsStr.replaceAll("\"\"", "null");
			if(columnsStr.indexOf("\"beanName\":\"fileProcess\"") != -1){
				 JSONArray jsonDataArray = JSONArray.fromObject(columnsStr);
				 for(Object obj :  jsonDataArray){
					 JSONObject json = (JSONObject)obj;
					 if(json.optJSONObject("process") == null){
						 continue;
					 }
					 JSONArray optJSONArray = json.optJSONObject("process").optJSONArray("html");
					 JSONObject optJSONObject = json.optJSONObject("process");
					 for(Object cobj :  optJSONArray){
						 JSONObject cjson = (JSONObject)cobj;
						 
						 if(cjson.optString("customize").indexOf("<select")!=-1){
							 
							 String url = cjson.optString("value");
							 String dbjsonFile = JsonUtils.getDBJSONFile(url);
							 
							 if(optJSONObject.optJSONArray("childColumn") == null){
								 
								 optJSONObject.put("childColumn", dbjsonFile);
							 }
						 };
					 }
					 //.optJSONArray("value");
				 }
				 columnsStr = jsonDataArray.toString();
			 }
			
			
			JSONArray fromObject = JSONArray.fromObject(columnsStr);
			Map<String,Class> classMap = new HashMap<>();
	        classMap.put("childColumn", Columns.class);
	        classMap.put("html", HtmlBean.class);
	        
			List<Columns> columns = new ArrayList<Columns>();
			for(Object obj : fromObject){
				JSONObject json = JSONObject.fromObject(obj);
				//JSONObject.toBean(json.getJSONObject("process").optJSONArray("childColumn"), Columns.class)
				Columns bean = (Columns)JSONObject.toBean(json, Columns.class, classMap);
				/*JSONArray html = json.getJSONObject("process").getJSONArray("html");
				for(Object htmlObj : html){
					JSONObject htmlJson = JSONObject.fromObject(htmlObj);
					HtmlBean htmlBean = (HtmlBean) htmlJson.toBean(htmlJson, HtmlBean.class);
					bean.getProcess().addHtml(htmlBean);
				}*/
				columns.add(bean);
			}
			
			List<CaseInsensitiveMap> objList = BaseProcess.packInsert(number, columns);
			Map<String, List<Map<String, Object>>> resultMap = new HashMap<String, List<Map<String, Object>>>();
			for(Map<String, Object> obj : objList){
				
				List<Map<String, Object>> arr = new ArrayList<Map<String, Object>>(1);
				arr.add(obj);
				
				String dbNamestr = (String)obj.get("dbName");
				String tableNamestr = (String)obj.get("tableName");
				
				List<Map<String, Object>> list = resultMap.get(dbNamestr+"."+tableNamestr);
				if(list == null){
					
					list = new ArrayList<Map<String, Object>>();
					resultMap.put(dbNamestr+"."+tableNamestr, list);
				}
				obj.remove("dbName");
				obj.remove("tableName");
				list.add(obj);
//				resultMap.put(dbNamestr+"."+tableNamestr, value);
			}
			for(String key : resultMap.keySet()){
				List<Map<String, Object>> list = resultMap.get(key);
				String[] split = key.split("\\.");
				String dbNamestr = split[0];
				String tableNamestr = split[1];
				dataBatchInsertCustomService.insertByBatchReturnCountHistory(list, dbNamestr, tableNamestr, null);
			}
			JSONObject json = new JSONObject();
			json.put("code", true);
			return json;
		}  catch (Exception e) {
			e.printStackTrace();
			JSONObject json = new JSONObject();
			json.put("code", false);
			if(e.getMessage() != null){
				
				json.put("msg", e.getMessage());
			}else{
				
				json.put("msg", e.getCause().getMessage());
			}
			return json;
		}
	}

	
	@SuppressWarnings("unchecked")
	@PostMapping("/save")
	@ResponseBody
	public Object save(String dbName,String tableName,String columnsStr){
		
		 
		 if(columnsStr.indexOf("\"beanName\":\"fileProcess\"") != -1){
			 JSONArray jsonDataArray = JSONArray.fromObject(columnsStr);
			 for(Object obj :  jsonDataArray){
				 JSONObject json = (JSONObject)obj;
				 if(json.optJSONObject("process") == null){
					 continue;
				 }
				 JSONArray optJSONArray = json.optJSONObject("process").optJSONArray("html");
				 JSONObject optJSONObject = json.optJSONObject("process");
				 for(Object cobj :  optJSONArray){
					 JSONObject cjson = (JSONObject)cobj;
					 
					 if(cjson.optString("customize").indexOf("<select")!=-1){
						 
						 String url = cjson.optString("value");
						 String dbjsonFile = JsonUtils.getDBJSONFile(url);
						 optJSONObject.put("childColumn", dbjsonFile);
					 };
				 }
				 //.optJSONArray("value");
			 }
			 
			 return JsonUtils.createDBJSONFile(jsonDataArray.toString(), tableName, dbName);
		 }
		
		 return JsonUtils.createDBJSONFile(columnsStr, tableName, dbName);
		
	}
	@GetMapping("/getConfig")
	@ResponseBody
	public Object getConfig(){
		
		List<File> list = new ArrayList<File>();
		FileUtils.getFiles(list, UrlUtil.getPath());
		
		List<FileBean> files = new ArrayList<FileBean>();
		for(File file : list){
			files.add(new FileBean(file.getName(),file.getPath().replace("\\", "/")));
		}
		return files;
		
	}
	@JsonIgnoreProperties({ "handler","hibernateLazyInitializer" })
	@PostMapping("/getConfigContent")
	@ResponseBody
	public Object getConfigContent(String url){
		String dbjsonFile = JsonUtils.getDBJSONFile(url);
		dbjsonFile = dbjsonFile.replaceAll("null", "\"\"");
		JSONObject json = new JSONObject();
		json.put("file", url);
		json.put("data", JSONArray.fromObject(dbjsonFile));
		return json;
		
	}
	public static String replacer(StringBuffer outBuffer) {
		  String data = outBuffer.toString();
		  try {
		     data = data.replaceAll("%(?![0-9a-fA-F]{2})", "%25");
		     data = data.replaceAll("\\+", "%2B");
		     data = URLDecoder.decode(data, "utf-8");
		  } catch (Exception e) {
		     e.printStackTrace();
		  }
		  return data;
		}
	//将Unicode编码转换成中文
    public  String decodeUnicode(String dataStr) {     
        int start = 0;     
        int end = 0;     
        final StringBuffer buffer = new StringBuffer();     
        while (start > -1) {     
            end = dataStr.indexOf("\\u", start + 2);     
            String charStr = "";     
            if (end == -1) {     
                charStr = dataStr.substring(start + 2, dataStr.length());     
            } else {     
                charStr = dataStr.substring(start + 2, end);     
            }     
            char letter = (char) Integer.parseInt(charStr, 16); // 16进制parse整形字符串。     
            buffer.append(new Character(letter).toString());     
            start = end;     
        }     
        return buffer.toString();     
     }
	private static String utf8Togb2312(String str){
	      StringBuffer sb = new StringBuffer();
	      for(int i=0; i<str.length(); i++) {
	          char c = str.charAt(i);
	          switch (c) {
	             case '+':
	                 sb.append(' ');
	             break;
	             case '%':
	                 try {
	                      sb.append((char)Integer.parseInt(
	                      str.substring(i+1,i+3),16));
	                 }
	                 catch (NumberFormatException e) {
	                     throw new IllegalArgumentException();
	                }
	                i += 2;
	                break;
	             default:
	                sb.append(c);
	                break;
	           }
	      }
	      // Undo conversion to external encoding
	      String result = sb.toString();
	      String res=null;
	      try{
	          byte[] inputBytes = result.getBytes("8859_1");
	          res= new String(inputBytes,"UTF-8");
	      }
	      catch(Exception e){}
	      return res;
	}

	
}